#include <stdio.h>
#include <aos/kernel.h>
#include <ulog/ulog.h>
#include "aos/hal/i2c.h"
#include "aos/hal/mipi_csi.h"
//#include "hal/hal_api.h"
#include "drv_isp.h"
#include "pin_name.h"
#include "camera_config.h"
#include "mm_config.h"
#include "drv_isp.h"
// #include "image_proc.h"
#include "iic_function.h"
#include "mipi_function.h"
#include "drv_mipi_csi.h"

#define EXAMPLE_MIPI_READER 0

extern volatile int g_rgb_img_ready;

mipi_csi_dev_t  pcsi_mipi[MIPI_NUM];
mipi_csi_reader_dev_t pcsi_mipi_reader;
volatile uint32_t *mipiSel = (volatile uint32_t *)(0xffd44040);  //CSKY_MIPI2DMA_BASE  MIPI_SEL


void mipi2isp_channel_start(uint32_t mipiID,uint32_t ispID)
{
#if 0
	uint32_t isp_temp;
	isp_temp = *mipiSel;
    isp_temp &= ~(0x7 << (4*ispID)); 	//bit 4 5 6 clear 0
    if(MIPI_0 == mipiID)
    	isp_temp |= (0x1 << (4*ispID)); //MIPI0 > ISPn
    else if(MIPI_1 == mipiID)
		isp_temp |= (0x2 << (4*ispID)); //MIPI1 > ISPn
    else if(MIPI_2 == mipiID)
		isp_temp |= (0x4 << (4*ispID)); //MIPI2 > ISPn
    *mipiSel = isp_temp;
#endif
}

void mipi2isp_channel_stop(uint32_t mipiID,uint32_t ispID)
{
#if 0
	uint32_t isp_temp;

	isp_temp = *mipiSel;
    isp_temp &= ~(0x7 << (4*ispID)); 	//bit 4 5 6 clear 0
    *mipiSel = isp_temp;
#endif
}

int mipi1_mipi2dma_stop(void)
{
#if 0
#if 0
	csi_mipi_csi_reader_stop(&pcsi_mipi_reader);
#else
    uint32_t isp_temp;
    isp_temp = *mipiSel;
    isp_temp &= ~(0x7 << 8); //bit 4 5 6 clear 0
    *mipiSel = isp_temp;
#endif

#endif
    return 0;
}

int mipi1_mipi2dma_start(void)
{
#if 0

#if 0
	mipi2dma_start(&pcsi_mipi_reader);
#else
    uint32_t isp_temp;
    isp_temp = *mipiSel;
    isp_temp &= ~(0x7 << 8); //bit 4 5 6 clear 0
    isp_temp |= (0x2 << 8); //bit 4 5 6 clear 0
    *mipiSel = isp_temp;
#endif

#endif
    return 0;
}

#if defined(AOS_BOARD_TX510_EG_360)
void mipi_clock_init(const imageChannel_t *image_ch)
{
    volatile uint32_t *ptr;
    ptr  = (volatile uint32_t *)0xfff26200;//mipi 0
                                           // *ptr = 0x1371c;
    *ptr = 0x13700;
    ptr  = (volatile uint32_t *)0xfff26204;//mipi 1
    //*ptr = 0x1351c;
    *ptr = 0x13500;
    ptr  = (volatile uint32_t *)0xfff26208;//mipi 2
    //*ptr = 0x1351c;
    *ptr = 0x13500;
}
#elif defined(AOS_BOARD_TX510_SLT)
void mipi_clock_init(const imageChannel_t *image_ch)
{
    volatile uint32_t *ptr;
    ptr  = (volatile uint32_t *)0xfff26200;//mipi 0
    *ptr = 0x1141c;
    ptr  = (volatile uint32_t *)0xfff26204;//mipi 1
    *ptr = 0x1141c;
    ptr  = (volatile uint32_t *)0xfff26208;//mipi 2
    *ptr = 0x1141c;
}
#else
void mipi_clock_init(const imageChannel_t *image_ch)
{
    volatile uint32_t *ptr = NULL;
    if (MIPI_0 == image_ch->mipi_ch)
    {
        ptr = (volatile uint32_t *)0xfff26200;
    }
    else if (MIPI_1 == image_ch->mipi_ch)
    {
        ptr = (volatile uint32_t *)0xfff26204;
    }
    else if (MIPI_2 == image_ch->mipi_ch)
    {
        ptr = (volatile uint32_t *)0xfff26208;
    }
    if (ptr != NULL)
    {
        *ptr = image_ch->mipi_clk;
    }
}
#endif


int mipi_init(int mipi_id)
{
    memset(&pcsi_mipi[mipi_id], 0, sizeof(mipi_csi_dev_t));
    pcsi_mipi[mipi_id].idx = mipi_id;
    hal_mipi_csi_init(&pcsi_mipi[mipi_id]);

    return 0;
}


int mipi_config(const imageChannel_t *image_ch)
{
    mipi_csi_config_t mipi_csi_config;
    imageFormat_t cfg = image_ch->in;
    mipi_clock_init(image_ch);


    if (R_1080P == cfg.res && RAW10 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 2;
        printf("set mipi conifg: raw10, 2lane,\n");
    }
	else if(R_1080x1280 == cfg.res && RAW10 ==cfg.format)
	{
		mipi_csi_config.data_format = MIPI_RAW10;
		mipi_csi_config.lane_count = 1;
		printf("set sc132 mipi conifg: raw10, 1lane,\n");
	}
    else if (R_1080P == cfg.res && YUV422 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_YUV422_8;
        mipi_csi_config.lane_count = 2;
    }
    else if(R_720P == cfg.res && YUV422 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_YUV422_8;
        mipi_csi_config.lane_count = 1;
    }
    else if (R_720P == cfg.res && RAW10 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 1;
    }
    else if(R_720P == cfg.res && RAW8 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW8;
        mipi_csi_config.lane_count = 1;
    }
    else if(R_1280x800 == cfg.res && RAW8 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW8;
        mipi_csi_config.lane_count = 2;
    }
    else if(R_640x241x5 == cfg.res && RAW12 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW12;
        mipi_csi_config.lane_count = 2;
        printf("irs2877c: mipi_config, raw12, 2lane. \n");
    }
    else if(R_1280x962 == cfg.res && RAW10 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 2;
        printf("s5k33d mipi_config, raw12, 2lane. \n");
    }
    else if(R_640x480 == cfg.res && RAW10 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 1;
        printf("sc031gs mipi_config, raw10, 1lane. \n");
    }
    else if(R_640x480 == cfg.res && RAW8 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW8;
        mipi_csi_config.lane_count = 1;
        printf("sc031gs mipi_config, raw8, 1lane. \n");
    }
    else if (R_720P == cfg.res && RAW12 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW12;
        mipi_csi_config.lane_count = 1;
    }
    else if(R_1600x1200 == cfg.res && RAW8 ==cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW8;
        mipi_csi_config.lane_count = 1;
    }
    else if (R_1600x1200 == cfg.res && RAW10 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 1;
    }
    else
    {
        printf("mipi_config format not support! \n");
    }

    int ret = hal_mipi_csi_config(&pcsi_mipi[image_ch->mipi_ch], &mipi_csi_config);
    if (ret != 0)
    {
        printf("mipi config error\n");
        return -1;
    }
    return 0;
}


int mipi_config_7022(int mipi_id, imageFormat_t cfg)
{
    mipi_csi_config_t mipi_csi_config;
    // imageChannel_t *image_ch_cahe = NULL;

#if defined(AOS_BOARD_TX510_EG_360) || defined(AOS_BOARD_TX510_SLT)
    mipi_clock_init(image_ch_cahe);
#endif
    if(R_1080P == cfg.res && RAW10 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 2;
        printf("set mipi conifg: raw10, 2lane,\n");
    }
    else if (R_1080P == cfg.res && YUV422 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_YUV422_8;
        mipi_csi_config.lane_count = 2;
    }
    else if (R_720P == cfg.res && YUV422 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_YUV422_8;
        mipi_csi_config.lane_count = 1;
    }
    else if (R_720P == cfg.res && RAW10 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW10;
        mipi_csi_config.lane_count = 1;
    }
    else if (R_720P == cfg.res && RAW8 == cfg.format)
    {
        mipi_csi_config.data_format = MIPI_RAW8;
        mipi_csi_config.lane_count = 1;
    }
    else
    {
        printf("mipi_config format not support! \n");
    }

    mipi_csi_config.xc7022_flg = 0xaa;
    int ret = hal_mipi_csi_config(&pcsi_mipi[mipi_id], &mipi_csi_config);
    if (ret != 0)
    {
        printf("mipi config error\n");
        return -1;
    }
    return 0;
}


int mipi_init_reader(int mipi_id, int isp_id)
{
    pcsi_mipi_reader.idx = EXAMPLE_MIPI_READER;
    hal_mipi_csi_reader_init(&pcsi_mipi_reader);

    /* Config the mipi csi reader */
    mipi_csi_reader_config_t mcr_input;
    /* Set the data addr in DDR */
    mcr_input.mode = ISP_MODE;
    mcr_input.mipi_id = mipi_id;
    mcr_input.isp_id = isp_id;
    int ret = hal_mipi_csi_reader_config(&pcsi_mipi_reader, &mcr_input);
    if (ret != 0)
    {
        printf("start mipi csi reader fail\n");
        return -1;
    }
    return 0;
}


int mipi_restart(int mipi_id)
{
    drv_mipi_restart(pcsi_mipi[mipi_id].priv);
    return 0;
}


